package com.scau.classOnline.service;

import com.scau.classOnline.common.DateUtil;
import com.scau.classOnline.common.TimetableStyle;
import com.scau.classOnline.common.UserUtils;
import com.scau.classOnline.dao.*;
import com.scau.classOnline.dto.CourseDTO;
import com.scau.classOnline.dto.CourseScheduleDTO;
import com.scau.classOnline.entity.*;
import com.scau.classOnline.model.*;
import com.scau.classOnline.utils.time.TimeFormatUtil;
import com.scau.classOnline.utils.time.TimePattern;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Service
@Transactional
public class CourseService {

    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private ScheduleMapper scheduleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private TakeMapper takeMapper;

    @Autowired
    private FileMapper fileMapper;


    public String[][] getSchedule(int id, Date day, int row, int col) {
        String[][] schedule = new String[row][col];
        int today = DateUtil.getWeekOfDay(day) - 1;
        if (today == -1) {
            today = 6;
        }
        for (int i = 0; i < row; i++) {
            List<Schedule> schedules = scheduleMapper.selectByStuIdAndInterval(id, day, i - today);
            for (Schedule item : schedules) {
                if (item.getFinished() == true) {
                    schedule[i][item.getTimeId()] = item.getCtitle() + "\n" + item.getTitle() + "\n" + "已结束";
                } else {
                    schedule[i][item.getTimeId()] = item.getCtitle() + "\n" + item.getTitle();
                }
            }
        }
        return schedule;
    }

    public String[][] getTeaSchedule(int id, Date day, int row, int col) {
        String[][] schedule = new String[row][col];
        int today = DateUtil.getWeekOfDay(day) - 1;
        if (today == 0) {
            today = 6;
        }
        for (int i = 0; i < row; i++) {
            List<Schedule> schedules = scheduleMapper.selectByTeaIdAndInterval(id, day, i - today);
            for (Schedule item : schedules) {
                schedule[i][item.getTimeId()] = item.getCtitle() + "\n" + item.getTitle();
            }
        }
        for (int i = 0; i < schedule.length; i++) {
            StringBuilder builder = new StringBuilder();
            builder.append("[");
            for (int j = 0; j < schedule[i].length; j++) {
                builder.append(schedule[i][j]).append(", ");
            }
            builder.append("]");
            System.out.println(builder);
        }
        return schedule;
    }

    public CourseDetailModel getCourseDetailById(Integer id) {
        Course course = courseMapper.selectByPrimaryKey(id);
        // todo exception
        User user = userMapper.selectByPrimaryKey(course.getUid());
//        User user = UserUtils.getCurrentUser();
        // todo exception
        CourseDetailModel courseDetailModel = new CourseDetailModel();
        UserDetailModel userDetailModel = new UserDetailModel();

        BeanUtils.copyProperties(user, userDetailModel);
        userDetailModel.setCreateTime(TimeFormatUtil.convertDateToString(user.getCreateTime(), TimePattern.SECOND));

        BeanUtils.copyProperties(course, courseDetailModel);
        courseDetailModel.setCreateTime(TimeFormatUtil.convertDateToString(course.getCreateTime(), TimePattern.SECOND));
        courseDetailModel.setUserDetailModel(userDetailModel);

        List<Schedule> schedules = scheduleMapper.selectByCid(id);
        List<SimpleScheduleModel> simpleScheduleModelList = schedules.stream().map(e -> {
            SimpleScheduleModel simpleScheduleModel = new SimpleScheduleModel();
            BeanUtils.copyProperties(e, simpleScheduleModel);
            simpleScheduleModel.setDate(TimeFormatUtil.convertDateToString(e.getDate(), TimePattern.DAY));
            simpleScheduleModel.setTimeInfo(TimetableStyle.timetableType[e.getTimeId()][1]);
            if (e.getFileid() != null) {
                File file = fileMapper.selectByPrimaryKey(e.getFileid());
                simpleScheduleModel.setFileUrl(file.getUrl());
            }
            return simpleScheduleModel;
        }).collect(Collectors.toList());
        courseDetailModel.setSimpleScheduleModels(simpleScheduleModelList);
        return courseDetailModel;
    }

    @Transactional
    public boolean modifyCourseById(CourseDTO courseDTO) {
        Course course = new Course();
        BeanUtils.copyProperties(courseDTO, course);
        int result = courseMapper.updateByPrimaryKey(course);
        // todo exception
        if (result <= 0) {
            return false;
        }
        return true;
    }

    @Transactional
    public boolean addCourse(CourseScheduleDTO courseScheduleDTO) {
        Course course = new Course();
        BeanUtils.copyProperties(courseScheduleDTO, course);
        int insert = courseMapper.insert(course);
        if (insert <= 0) {
            return false;
        }
        courseScheduleDTO.getScheduleDTOList().forEach(e -> {
            e.setCid(course.getId());
            boolean result = scheduleService.addSchedule(e);
            if (!result) {
                // todo 抛异常！！
            }
        });
        return true;
    }

    public List<CourseListModel> getCoursesByPages(Integer start, Integer count) {
        List<Course> courses = courseMapper.selectByPages(start, count);
        return convertCoursesToListModels(courses);
    }

    public List<CourseListModel> getCoursesByFuzzy(String pattern) {
        List<Course> courses = courseMapper.selectByTitle(pattern);
        List<User> users = userMapper.selectTeacherByUsername(pattern);
        users.forEach(e -> {
            List<Course> addCourses = courseMapper.selectByTeacherId(e.getId());
            courses.addAll(addCourses);
        });
        return convertCoursesToListModels(courses);
    }

    private List<CourseListModel> convertCoursesToListModels(List<Course> courses) {
        List<CourseListModel> listModels = courses.stream().map(e -> {
            CourseListModel courseListModel = new CourseListModel();
            BeanUtils.copyProperties(e, courseListModel);
            User user = userMapper.selectByPrimaryKey(courseListModel.getUid());
            courseListModel.setUsername(user.getUsername());
            courseListModel.setName(user.getName());
            return courseListModel;
        }).collect(Collectors.toList());

        //去重操作
        Set<CourseListModel> set = new LinkedHashSet<>(listModels);
        listModels.clear();
        listModels.addAll(set);
        return listModels;
    }

    public int bookCourse(Integer sid, Integer cid) {
        return takeMapper.insert(sid, cid);
    }

    public int cancelCourse(Integer sid, Integer cid) {
        return takeMapper.deleteBySidAndCid(sid, cid);
    }

    public Take getBookCourse(Integer sid, Integer cid) {
        return takeMapper.selectBySidAndCid(sid, cid);
    }

    public List<CourseDetailModel> getCourseByTeaId(Integer uid) {
        List<Course> courses = courseMapper.selectByTeacherId(uid);
        List<CourseDetailModel> collect = courses.stream().map(e -> {
            CourseDetailModel courseDetailModel = new CourseDetailModel();
            BeanUtils.copyProperties(e, courseDetailModel);
            courseDetailModel.setCreateTime(TimeFormatUtil.convertDateToString(e.getCreateTime(), TimePattern.SECOND));
            return courseDetailModel;
        }).collect(Collectors.toList());
        return collect;
    }

    public List<UserTakeModel> getCourseByStuId(Integer uid) {
        List<Take> takes = takeMapper.selectByStuId(uid);
        List<UserTakeModel> collect = takes.stream().map(e -> {
            UserTakeModel userTakeModel = new UserTakeModel();
            Course course = courseMapper.selectByPrimaryKey(e.getCid());
            BeanUtils.copyProperties(course, userTakeModel);
            userTakeModel.setCid(e.getCid());
            userTakeModel.setTakeTime(TimeFormatUtil.convertDateToString(e.getCreateTime(), TimePattern.SECOND));
            return userTakeModel;
        }).collect(Collectors.toList());
        return collect;
    }

    public int setFinished(Integer id) {
        Course course = courseMapper.selectByPrimaryKey(id);
        if (course != null) {
            course.setFinished(true);
            int i = courseMapper.setFinishedById(course);
            if (i == 1) {
                return 1;
            } else {
                return 0;
            }
        }
        return -1;
    }
}
